package com.bins.dentist.clinic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bins.dentist.clinic.constants.CommonConstants;
import com.bins.dentist.clinic.constants.UserConstants;
import com.bins.dentist.clinic.enums.UserStatusEnum;
import com.bins.dentist.clinic.mapper.UserMapper;
import com.bins.dentist.clinic.model.dto.UserDto;
import com.bins.dentist.clinic.model.dto.UserPageDto;
import com.bins.dentist.clinic.entity.UserEntity;
import com.bins.dentist.clinic.model.vo.LoginVo;
import com.bins.dentist.clinic.model.vo.UserPageVo;
import com.bins.dentist.clinic.model.vo.UserVo;
import com.bins.dentist.clinic.service.UserService;
import com.bins.dentist.clinic.utils.GenerateUtil;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author bins
 * @since 2023-02-20 20:53:31
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public IPage getPage(UserPageDto pageDto) {
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(!ObjectUtils.isEmpty(pageDto.getUserCode()), UserEntity::getUserCode, pageDto.getUserCode())
                .like(!ObjectUtils.isEmpty(pageDto.getUserName()), UserEntity::getUserName, pageDto.getUserName())
                .eq(!ObjectUtils.isEmpty(pageDto.getPhone()), UserEntity::getPhone, pageDto.getPhone())
                .eq(!ObjectUtils.isEmpty(pageDto.getStatus()), UserEntity::getStatus, pageDto.getStatus())
                .eq(UserEntity::getIsDel, CommonConstants.DELETED_NO);
        IPage page = userMapper.selectPage(new Page(pageDto.getPageNum(), pageDto.getPageSize()), queryWrapper);
        List<UserEntity> userPageList = page.getRecords();
        if (CollectionUtils.isEmpty(userPageList)) {
            return page;
        }
        List<UserPageVo> userList = Lists.newArrayListWithCapacity(userPageList.size());
        for (UserEntity userEntity : userPageList) {
            UserPageVo userVo = new UserPageVo();
            BeanUtils.copyProperties(userEntity, userVo);
            userVo.setStatusName(UserStatusEnum.getUserStatusName(userEntity.getStatus()));
            userList.add(userVo);
        }
        page.setRecords(userList);
        return page;
    }

    @Override
    public UserVo saveUser(UserDto dto) {
        UserEntity userEntity = new UserEntity();
        if (ObjectUtils.isEmpty(dto.getId())) {
            BeanUtils.copyProperties(dto, userEntity);
            userEntity.setUserCode(GenerateUtil.generateUserCode(""));
            userEntity.setStatus(UserStatusEnum.VALID.getStatus());
            userEntity.setAvatar(UserConstants.DEFAULT_AVATAR);
            userEntity.setPassword(UserConstants.DEFAULT_PASSWORD);
            userEntity.setIsDel(CommonConstants.DELETED_NO);
            userEntity.setDeptId(CommonConstants.DELETED_DEPT);
            userEntity.setUserGroupId(CommonConstants.DELETED_USER_GROUP);
            userEntity.setCreateBy(0l);
            userEntity.setUpdateBy(0l);
            userEntity.setCreateTime(LocalDateTime.now());
            userEntity.setUpdateTime(LocalDateTime.now());
            userMapper.insert(userEntity);
        } else {
            userEntity.setId(dto.getId());
            userEntity.setUserName(dto.getUserName());
            userEntity.setNickName(dto.getNickName());
            userEntity.setPhone(dto.getPhone());
            userEntity.setEmail(dto.getEmail());
            userMapper.updateById(userEntity);
        }
        UserVo userVo = new UserVo();
        userVo.setId(userEntity.getId());
        userVo.setUserName(userEntity.getUserName());
        return userVo;
    }

    @Override
    public UserVo userDetail(UserDto dto) {
        UserEntity userEntity = userMapper.selectById(dto.getId());
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(userEntity, userVo);
        userVo.setStatusName(UserStatusEnum.getUserStatusName(userEntity.getStatus()));
        return userVo;
    }

    @Override
    public UserVo deleteUser(UserDto dto) {
        UserEntity userEntity = userMapper.selectById(dto.getId());
        UserEntity user = new UserEntity();
        user.setId(userEntity.getId());
        user.setIsDel(CommonConstants.DELETED_YES);
        userMapper.updateById(user);
        UserVo userVo = new UserVo();
        userVo.setId(userEntity.getId());
        return userVo;
    }

    @Override
    public UserVo refreshCache(UserDto dto) {
        UserEntity userEntity = userMapper.selectById(dto.getId());
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(userEntity, userVo);
        userVo.setStatusName(UserStatusEnum.getUserStatusName(userEntity.getStatus()));
        return userVo;
    }

    @Override
    public UserVo offlineUser(UserDto dto) {
        UserEntity userEntity = userMapper.selectById(dto.getId());
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(userEntity, userVo);
        userVo.setStatusName(UserStatusEnum.getUserStatusName(userEntity.getStatus()));
        return userVo;
    }

    @Override
    public UserVo resetPassword(UserDto dto) {
        UserEntity userEntity = userMapper.selectById(dto.getId());
        UserEntity update = new UserEntity();
        update.setId(dto.getId());
        update.setPassword(UserConstants.DEFAULT_PASSWORD);
        userMapper.updateById(update);
        UserVo userVo = new UserVo();
        userVo.setId(userEntity.getId());
        userVo.setUserName(userEntity.getUserName());
        return userVo;
    }

    @Override
    public UserVo updateLockStatus(UserDto dto) {
        UserEntity userEntity = userMapper.selectById(dto.getId());
        UserEntity update = new UserEntity();
        update.setId(dto.getId());
        if (!ObjectUtils.isEmpty(dto.getLockFlag()) && "Y".equalsIgnoreCase(dto.getLockFlag())) {
            update.setStatus(2);
        } else {
            update.setStatus(1);
        }
        userMapper.updateById(update);
        UserVo userVo = new UserVo();
        userVo.setId(userEntity.getId());
        userVo.setUserName(userEntity.getUserName());
        return userVo;
    }

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(UserEntity::getIsDel, CommonConstants.DELETED_NO)
                .eq(UserEntity::getUserCode, userName);
        UserEntity userEntity = userMapper.selectOne(queryWrapper);
        LoginVo userDetails = new LoginVo();
        userDetails.setUsername(userEntity.getUserName());
        userDetails.setPassword(userEntity.getPassword());
        return userDetails;

    }
}
